package edu.hubu.shop9.util;

import edu.hubu.shop9.entity.Product;
import edu.hubu.shop9.service.IProductService;
import edu.hubu.shop9.service.IProductTypeService;
import edu.hubu.shop9.service.ISystemDictionaryDetailService;
import edu.hubu.shop9.service.ISystemDictionaryTypeService;
import edu.hubu.shop9.vo.ProductVo;

import java.io.*;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author waxijiang
 */
public class ObjectUtils {

    /**
     * 获取对象非空属性
     *
     * @param o
     * @return
     */
    public static Map<String, Object> getNotNullFields(Object o) {
//        HashMap<String, Object> map = new HashMap<String, Object>();

        return Arrays.stream(o.getClass().getDeclaredFields())
                .peek(field -> field.setAccessible(true))
                .filter(f -> {
                    try {
                        return !(Modifier.isStrict(f.getModifiers()) || Modifier.isFinal(f.getModifiers())) && !(f.get(o) == null) && !("deleted".equals(f.getName()) || "forbidden".equals(f.getName()) || "finished".equals(f.getName()));
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }).collect(Collectors.toMap(field -> transferCamelName(field.getName()), field -> {
                    try {
                        return field.get(o);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }));

    }

    private static String transferCamelName(String name) {
        StringBuilder builder = new StringBuilder(name);
        // 驼峰转数据表字段名
        for (char c : name.toCharArray()) {
            if (c > 65 && c < 90) {
                int index = name.indexOf(c);
                char c1 = builder.charAt(index);
                c1 += 32;
                builder.deleteCharAt(index);
                builder.insert(index, "_" + c1);

            }
        }
        return builder.toString();
    }

    /**
     * 对象转数组
     *
     * @param o
     * @return
     */
    public static byte[] toByteArray(Object o) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = null;
        try {
            objectOutputStream = new ObjectOutputStream(outputStream);
            objectOutputStream.writeObject(o);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return outputStream.toByteArray();
    }

    /**
     * 数组转对象
     *
     * @param bytes
     * @return
     */
    public static <T> T toObject(byte[] bytes, Class<T> aClass) {
        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException | ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return (T) obj;
    }

    public static ProductVo wrapperProduct(Product p, IProductTypeService productTypeService,
                                           ISystemDictionaryTypeService systemDictionaryTypeService,
                                           ISystemDictionaryDetailService systemDictionaryDetailService) {
        ProductVo vo = new ProductVo();
        vo.setId(p.getId());
        vo.setName(p.getName());
        vo.setPic(p.getPic());
        vo.setSmallpic(p.getSmallpic());
        vo.setColor(p.getColor());
        vo.setCostprice(p.getCostprice());
        vo.setSaleprice(p.getSaleprice());
        vo.setType(productTypeService.getById(p.getTypesId()).getName());
        vo.setTypesId(p.getTypesId());
        vo.setUnit(systemDictionaryDetailService.getById(p.getUnitId()).getName());
        vo.setUnitId(p.getUnitId());
        vo.setBrand(systemDictionaryDetailService.getById(p.getBrandId()).getName());
        vo.setBrandId(p.getBrandId());
        return vo;
    }
}
